Use case: Communication in interrupt mode ¶
The FDCAN interrupt management has been updated to use a more modular approach.
Interrupt to line configuration:
In HAL1, the configuration of FDCAN interrupt lines is performed using the
HAL_FDCAN_ConfigInterruptLines()function. When interrupt grouping is supported by the given STM32 device, grouped interrupt flags such asFDCAN_IT_GROUP_SMSGandFDCAN_IT_GROUP_RX_FIFO0are collectively assigned to the chosen interrupt line (line 0 and/or line 1). If interrupt grouping is not supported by the device, individual interrupt sources likeFDCAN_IT_TX_COMPLETEandFDCAN_IT_RX_FIFO0_NEW_MESSAGEare assigned directly to the chosen interrupt line (line 0 and/or line 1).In HAL2, when the interrupt grouping feature is available on the STM32 device,
HAL_FDCAN_SetInterruptGroupsToLine()is used to assign grouped interrupts (e.g.,HAL_FDCAN_IT_GROUP_STATUS_MSGandHAL_FDCAN_IT_GROUP_RX_FIFO_0) to the chosen interrupt line (line 0 and/or line 1). When interrupt grouping is not available,HAL_FDCAN_SetInterruptsToLine()is used to assign individual interrupts (e.g.,HAL_FDCAN_IT_TX_COMPLETEandHAL_FDCAN_IT_RX_FIFO_0_NEW_MSG) to the chosen interrupt line (line 0 and/or line 1).
|
Interrupt grouping feature |
HAL1 |
HAL2 |
|---|---|---|
|
Available |
Use
|
Use
|
|
Not available |
Use
|
Use
|
Interrupt activation
In HAL1, the function
HAL_FDCAN_ActivateNotification()is used to enable specific FDCAN interrupt notifications in a single call, meaning it enables both the requested interrupts and the interrupt line(s) (line 0 and/or line 1) on which the corresponding interrupts are set.In HAL2, interrupt management is designed to be more granular and modular:
HAL_FDCAN_EnableInterruptLines()is used to activate the interrupt line(s) (line 0 and/or line 1).HAL_FDCAN_EnableInterrupts()enables interrupt sources (e.g.HAL_FDCAN_IT_RX_FIFO_0_NEW_MSG).For transmit complete interrupts like
FDCAN_IT_TX_COMPLETE, the dedicated functionHAL_FDCAN_EnableTxBufferCompleteInterrupts()must also be called to enable the corresponding buffer interrupts.Similarly, for transmit abort interrupts such as
FDCAN_IT_TX_ABORT_COMPLETE, the functionHAL_FDCAN_EnableTxBufferCancellationInterrupts()must also be called.Additionally,
HAL_FDCAN_CCU_EnableInterrupts()is provided to enable clock calibration unit interrupts.
For more details see HAL FDCAN enables interrupt notifications..
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
/* if interrupt grouping available */
HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_GROUP_SMSG
| FDCAN_IT_GROUP_RX_FIFO0,
FDCAN_INTERRUPT_LINE0);
/* else */
HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_TX_COMPLETE
| FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
FDCAN_INTERRUPT_LINE0);
HAL_FDCAN_ActivateNotification(&hfdcan,
FDCAN_IT_TX_COMPLETE |
FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
FDCAN_TX_BUFFER0);
HAL_FDCAN_Start(&hfdcan);
/* Prepare FDCAN transmit message header */
TxHeader.Identifier = 0x111;
TxHeader.IdType = FDCAN_STANDARD_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_8;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan, &TxHeader, &TxData[0]);
while (TransmissionCompleteFlag == 0);
if (Notification_flag == 1)
{
HAL_FDCAN_GetRxMessage(&hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData);
Notification_flag = 0;
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
Notification_flag = 1;
}
}
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
TransmissionCompleteFlag = 1U;
}
|
/* if interrupt grouping */
HAL_FDCAN_SetInterruptGroupsToLine(&hfdcan, HAL_FDCAN_IT_GROUP_STATUS_MSG
| HAL_FDCAN_IT_GROUP_RX_FIFO_0 ,
HAL_FDCAN_IT_LINE_0 );
/* else */
HAL_FDCAN_SetInterruptsToLine(&hfdcan, HAL_FDCAN_IT_TX_COMPLETE
| HAL_FDCAN_IT_RX_FIFO_0_NEW_MSG ,
HAL_FDCAN_IT_LINE_0 );
HAL_FDCAN_EnableInterruptLines(&hfdcan, HAL_FDCAN_IT_LINE_0);
HAL_FDCAN_EnableTxBufferCompleteInterrupts(&hfdcan, HAL_FDCAN_IT_TX_CPLT_BUFFER_0);
HAL_FDCAN_EnableInterrupts(&hfdcan, HAL_FDCAN_IT_TX_COMPLETE | HAL_FDCAN_IT_RX_FIFO_0_NEW_MSG);
HAL_FDCAN_Start(&hfdcan);
/* Prepare FDCAN transmit message header */
tx_element_header.b.identifier = 0x111,
tx_element_header.b.identifier_type = HAL_FDCAN_ID_STANDARD,
tx_element_header.b.frame_type = HAL_FDCAN_FRAME_DATA,
tx_element_header.b.data_length = HAL_FDCAN_DATA_LEN_CAN_FDCAN_8_BYTE,
tx_element_header.b.error_state_indicator = HAL_FDCAN_ERROR_STATE_IND_ACTIVE,
tx_element_header.b.bit_rate_switch = HAL_FDCAN_BIT_RATE_SWITCH_ON,
tx_element_header.b.frame_format = HAL_FDCAN_HEADER_FRAME_FORMAT_FD_CAN,
tx_element_header.b.event_fifo_control = HAL_FDCAN_FIFO_STORE_TX_EVENTS,
tx_element_header.b.message_marker = 0U,
HAL_FDCAN_ReqTransmitMsgFromFIFOQ(hfdcan, &tx_element_header, pTxData);
while (TransmissionCompleteFlag == 0);
if (Notification_flag == 1)
{
HAL_FDCAN_GetReceivedMessage(hfdcan, HAL_FDCAN_RX_FIFO_0, &rx_element_header, RxBuffer);
ReceptionFlag = 0;
}
static void HAL_FDCAN_RxFifo0Callback(hal_fdcan_handle_t *hfdcan, uint32_t rx_fifo0_interrupts)
{
if((rx_fifo0_interrupts & HAL_FDCAN_IT_RX_FIFO_0_NEW_MSG) != RESET)
{
Notification_flag = 1;
}
}
static void HAL_FDCAN_TxBufferCompleteCallback(hal_fdcan_handle_t *hfdcan, uint32_t buffer_indexes)
{
TransmissionCompleteFlag = 1U;
}
|
Key changes ¶
HAL2 splits notification configuration into separate APIs to configure interrupts and interrupt line(s).
HAL2 provides dedicated APIs for enabling Tx buffer complete interrupts.
![@startuml
participant "User application" as App
participant "<font color=black><b>HAL FDCAN" as FDCAN #19DD3A
alt #LightSteelBlue Interrupt grouping available
App -> FDCAN: HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_GROUP_SMSG | FDCAN_IT_GROUP_RX_FIFO0, FDCAN_INTERRUPT_LINE0)
else #LightCyan else
App -> FDCAN: HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_TX_COMPLETE | FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0)
end
FDCAN --> App:<color green>HAL_OK
App -> FDCAN: HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_TX_COMPLETE | FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_TX_BUFFER0)
FDCAN --> App:<color green>HAL_OK
App -> FDCAN: HAL_FDCAN_Start()
FDCAN --> App:<color green>HAL_OK
Note over App#lightyellow: Prepare the Tx Header
== FDCAN HAL Message Transmit ==
App-> FDCAN: HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan, &TxHeader, TxData[0])
FDCAN --> App:<color green>HAL_OK
activate App #1000DA
hnote over App
<font color=blue>transmission ongoing...
end note
NVIC <- : FDCAN interrupt Tx Complete
NVIC -> FDCAN: HAL_FDCAN_IRQHandler
FDCAN -> App: HAL_FDCAN_TxBufferCompleteCallback()
Note over App#lightyellow: TransmissionCompleteFlag = 1U
App --> FDCAN:
deactivate App
FDCAN --> NVIC:
NVIC --> :
deactivate App
== FDCAN HAL Message Receive ==
NVIC <- : FDCAN interrupt Rx FIFO New Message
NVIC -> FDCAN: HAL_FDCAN_IRQHandler
FDCAN -> App: HAL_FDCAN_RxFifo0Callback()
Note over App#lightyellow: if(RxFifo0ITs = FDCAN_IT_RX_FIFO0_NEW_MESSAGE) \n Notification_flag = 1U
FDCAN <-- App
NVIC <-- FDCAN
NVIC --> :
alt Notification_flag == 1U
App -> FDCAN: HAL_FDCAN_GetRxMessage()
note right
Retrieve an FDCAN frame from the Rx FIFO
endnote
FDCAN --> App:<color green>HAL_OK
end
@enduml](../../../../../_images/plantuml-6a0905a2459043e4a4e835ba7de6bf9c3769f217.png)
